package com.ruoyi.project.sms.qcloud;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.google.gson.Gson;
import com.ruoyi.common.constant.SystemContstant;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.page.PageToList;
import com.ruoyi.project.content.PropertyTypeEnum;
import com.ruoyi.project.sms.ISMSService;
import com.ruoyi.project.utils.JsonUtils;
import com.ruoyi.project.utils.RedisUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 阿里云短信接口
 *
 * @author Administrator
 */
@Service (value = "alysms")
public class AliyunSmsServiceImpl implements ISMSService {

    private static final Logger log = LoggerFactory.getLogger(AliyunSmsServiceImpl.class);

    private static String accessKeyId = "LTAI5t7hDTcUBFZD6Y8Cf7Zr";

    private static String accessKeySecret = "ZuvvK4m4ZFg3OChqn8sODMY8Oo9jKK";

    private static String codekey = "SMS_219220110";//验证码码模板id

    // 于2023-02-28 更换新模板：SMS_271455465 原模板： SMS_219405320，
    // 于同日下午1点，更换新模板：SMS_271495511（IOS手机无法打开链接，因链接与文字连一起了）
    private static String yaoqinkey = "SMS_271495511";//验证码码模板id

    @Autowired
    private RedisUtils redisUtils;

    public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMAL04mTnVnpja84CEWe1Ztbh6vqOwJyKfm6LxjoOz6zzP8ZMY9v25naKus8aShIm90GtnnOl9dse4fXSzGgHe5yYvgd1FWO9LmYe1bHVuQq4kbRg69QjZivUI+lP9Cf2Y0hzJvf9eMQUJ3iYhVCUcS+TRaF9H/jQ2DpOluiqfIHAgMBAAECgYBYmhwycOQ7w0EXAebvF+S9FHF3o00uR7WN/ZQVDa+nshR17Q2se5L5XGpItUpex4EBbENr1yC+xtIHThDnCFRGDTw6B0YJ9hF4vHnMrVWluLps5xMHUdDQPC4n9hshJzjHWCTitoloFRcjtTh3rU2OZdJS9Cbb/BZjtSbYuO14wQJBAPDZP0c+T5G8GTHBwY4mpP+YRB9nG2hzXEmQWPHW7q+GKZcyGltONwG1FJM83Q6fjCE6slx6hNUc5/7+QflI718CQQDMIKOkSwgWhkskSlqswa3kz5FdRo1uUOE4JU4ibuIfP7lri66Q6e1u1H5mpcVPdOQE74B0K+qSLWIGW0aa3YZZAkAI/TK9Z/f0Sn7uOnsM4ShbWcWBHooJVfTl0ftf21PBPVKkD/yn17151NZVwHnHp/DE9LnfdbsrcQ6/l6HCuhQlAkEAhtKQAvWj0+zDOKb7mNsbleMa6fatd01oVAMfxlJie61FNKk/lWtMbUVgbz/SQJa9/ByMRS60cfQTqIsk6SijkQJAIAL++05CiLqDQVYUFDeVrjSSWvKnBj3eMvf9jcylCVHSfKu/OeCfEb5QDdEAbyCDKr2QgcbEEmeqATniqUbruw==";

    public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAC9OJk51Z6Y2vOAhFntWbW4er6jsCcin5ui8Y6Ds+s8z/GTGPb9uZ2irrPGkoSJvdBrZ5zpfXbHuH10sxoB3ucmL4HdRVjvS5mHtWx1bkKuJG0YOvUI2Yr1CPpT/Qn9mNIcyb3/XjEFCd4mIVQlHEvk0WhfR/40Ng6TpboqnyBwIDAQAB";


    /**
     * 使用AK&SK初始化账号Client
     *
     * @return Client
     *
     * @throws Exception
     */
    public static com.aliyun.dysmsapi20170525.Client createClient () throws Exception {
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    public static void main (String[] args_) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers("13267180272");//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(codekey);//短信模板id
        sendSmsRequest.setTemplateParam("{\"code\":\"111111\"}");
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        System.out.println(jsonObjects.get("code"));

        System.out.println(jsonObject.toString());

    }

    private String sendMsg (String mobile, String randomCode) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(codekey);//短信模板id
        sendSmsRequest.setTemplateParam("{\"code\":\"" + randomCode + "\"}");
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            log.info("发送短信成功", jsonObjects.get("message").toString());
            return jsonObjects.get("message").toString();
        } else {
            return "发送失败";
        }
    }

    @Override
    public String getMobile (String mobile) throws Exception {
        RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
        try {
            mobile = rsa.decryptStr(mobile, KeyType.PrivateKey);
        } catch (Exception e) {
            throw new RuntimeException("手机解密失败");
        }
        if (StringUtils.isBlank(mobile) || mobile.length() != 11) {
            throw new RuntimeException("手机号码错误");
        }
        return mobile;
    }

    /**
     * 解密数据
     *
     * @param str
     *         待解密的字符串
     *
     * @return
     */
    @Override
    public String decrypt (String str) throws Exception {
        if (StringUtils.isBlank(str)) {
            return StringUtils.EMPTY;
        }

        try {
            RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
            return rsa.decryptStr(str, KeyType.PrivateKey);
        } catch (Exception e) {
            throw new RuntimeException("解密支付密码出错");
        }
    }

    @Override
    public String sendCode (String mobile, Integer length) throws Exception {
        if (this.redisUtils.hasKey(SystemContstant.CHECK_CODES + mobile)) {
            return "发送成功";
        }
        this.redisUtils.set(SystemContstant.CHECK_CODES + mobile, 30, 30);

        //	System.err.println("发送阿里云短信");
        String randomCode = this.getRandomCode(length == null || length.intValue() == 0 ? 4 : length);
        String result = this.sendMsg(mobile, randomCode);
        //TODO 测试关闭短信发送
        if (!result.equals("发送失败")) {
            this.redisUtils.set(SystemContstant.CHECK_CODE + mobile, randomCode);
            this.redisUtils.expire(SystemContstant.CHECK_CODE + mobile, 70);
            return "发送成功";
        } else {
            return "发送失败";
        }
        //        return randomCode;
    }

    @Override
    public String sendGroupMsg (String[] mobiles, String[] msg) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendBatchSmsRequest sendBatchSmsRequest = new SendBatchSmsRequest();
        sendBatchSmsRequest.setPhoneNumberJson(mobiles.toString());
        String[] signNameJson = new String[mobiles.length - 1];
        for (int i = 0; i < mobiles.length; i++) {
            signNameJson[i] = "找零工";
        }

        sendBatchSmsRequest.setSignNameJson(signNameJson.toString());
        sendBatchSmsRequest.setTemplateCode(yaoqinkey);
        // 复制代码运行请自行打印 API 的返回值
        SendBatchSmsResponse sendBatchSmsResponse = client.sendBatchSms(sendBatchSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendBatchSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            return jsonObjects.get("message").toString();
        } else {
            return "发送失败";
        }
    }

    @Override
    public String sendservice (String mobile, String TemplateCode) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(TemplateCode);//短信模板id
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            return jsonObjects.get("message").toString();
        } else {
            return "发送失败";
        }

    }


    @Override
    public String sendYaoqing (String mobile, String username) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(yaoqinkey);//短信模板id
        //  sendSmsRequest.setTemplateParam("{\"name\":\""+username+"\"}");
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            return jsonObjects.get("message").toString();
        } else {
            return "发送失败";
        }
    }


    @Override
    public boolean checkSmsCode (String mobile, String checkCode) {
        String sysCheckCode = this.redisUtils.hget(PropertyTypeEnum.SYS.getText(), "sys_check_code") + "";
        if (sysCheckCode.equals(checkCode)) {
            this.redisUtils.del(SystemContstant.CHECK_CODE + mobile);
            return false;
        }
        //通过缓存获取手机验证码
        String code = this.redisUtils.get(SystemContstant.CHECK_CODE + mobile);
        if (StringUtils.isEmpty(code)) {
            return true;
        }
        //不相等时返回错误
        if (!code.equals(checkCode)) {
            return true;
        }
        return false;
    }

    //获取随机验证码
    @Override
    public String getRandomCode (int length) {
        StringBuffer code = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }


    @Override
    public void sendMarketingMsg (List <String> phones, String template) {
        if (CollectionUtils.isEmpty(phones) || StringUtils.isEmpty(template)) {
            log.error("发送营销短信，手机号码或者模板为空。手机号码：{}, 模板：{}", phones, template);
            return;
        }

        // 对号码进行去重复，并且对不是11位的手机号码过滤
        phones = phones.stream().filter(s -> {
            s = org.apache.commons.lang3.StringUtils.deleteWhitespace(s);
            return StringUtils.isNotBlank(s) && s.length() == 11;
        }).distinct().collect(Collectors.toList());

        // 总的数量
        int total = phones.size();
        int pageSize = 100;
        // 总页数
        PageToList page = new PageToList(pageSize, total);
        long totalPage = page.getTotalPages();

        for (int i = 1; i <= totalPage; i++) {
            //分页
            List <String> subList = phones.stream().skip(page.getStartPosition(i)).limit(pageSize)
                    .collect(Collectors.toList());

            if (CollectionUtils.isEmpty(subList)) {
                continue;
            }

            try {
                com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
                SendBatchSmsRequest sendBatchSmsRequest = new SendBatchSmsRequest();
                sendBatchSmsRequest.setPhoneNumberJson(JsonUtils.objectToJson(subList));
                List <String> signNameJson = new ArrayList <>();

                for (int j = 0; j < subList.size(); j++) {
                    signNameJson.add("找零工");
                }

                sendBatchSmsRequest.setSignNameJson(JsonUtils.objectToJson(signNameJson));
                sendBatchSmsRequest.setTemplateCode(template);
                client.sendBatchSms(sendBatchSmsRequest);
            } catch (Exception e) {
                log.error("批量发送营销短信失败", e);
            }
        }
    }

    @Override
    public void sendMsgByCode (String mobile, String code) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(code);//短信模板id
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            log.info("发送短信成功", "电话：" + mobile + "code：" + code + "  " + jsonObjects.get("message").toString());
        } else {
            log.error("发送短信失败", "电话：" + mobile + "code：" + code + "  " + jsonObjects.get("message").toString());
        }
    }

    @Override
    public Boolean sendMsgByCodeResult (String mobile, String code) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(code);//短信模板id
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        JSONObject jsonObject = JSON.parseObject(new Gson().toJson(sendSmsResponse));
        JSONObject jsonObjects = JSON.parseObject(new Gson().toJson(jsonObject.get("body")));

        if ("OK".equals(jsonObjects.get("code"))) {
            log.info("发送短信成功", "电话：" + mobile + "code：" + code + "  " + jsonObjects.get("message").toString());
            return true;
        } else {
            log.error("发送短信失败", "电话：" + mobile + "code：" + code + "  " + jsonObjects.get("message").toString());
            return false;
        }
    }

    @Override
    public void sendMsgByParameters(String mobile, String code, String templateParam) throws Exception {
        com.aliyun.dysmsapi20170525.Client client = AliyunSmsServiceImpl.createClient();
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(mobile);//接收手机号
        sendSmsRequest.setSignName("找零工");//签名名称
        sendSmsRequest.setTemplateCode(code);//短信模板id
        sendSmsRequest.setTemplateParam(templateParam);
        // 复制代码运行请自行打印 API 的返回值
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
    }


}
